package com.homedo.microservice.open.service.gateway.manager.web.service;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Lists;
import com.homedo.common.bean.data.enums.ResponseEnum;
import com.homedo.common.bean.vo.context.UserContext;
import com.homedo.common.dao.bean.po.base.BasePo;
import com.homedo.common.dao.conf.DruidConf;
import com.homedo.common.dao.util.DruidDataSourceUtil;
import com.homedo.common.exception.HomedoException;
import com.homedo.common.service.BaseService;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.DbSource;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.enhanced.DbSourceEnhanced;
import com.homedo.microservice.open.service.gateway.manager.web.persistence.dao.DbSourceDao;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

/**
 * @author 作者 jgshun
 * @date 创建时间 2018年09月21日 13时08分00秒
 */
@Service
public class DbSourceService extends BaseService<DbSource> {
    @Autowired
    private DbSourceDao dbSourceDao;
    @Autowired
    private DruidConf druidConf;


    @Override
    public List<DbSourceEnhanced> getEnhanceds(List<?> ids, UserContext userContext) {
        List<DbSource> dbSources = dbSourceDao.getListByIds(ids, DbSource.class);

        if (!Detect.notEmpty(dbSources)) {
            return null;
        }

        return this.convent2Enhanceds(dbSources);
    }


    @Override
    public List<DbSourceEnhanced> getEnhanceds4Active(List<?> ids, UserContext userContext) {
        List<DbSource> dbSources = dbSourceDao.getListByIdsGreaterThanMark0(ids, DbSource.class);

        if (!Detect.notEmpty(dbSources)) {
            return null;
        }

        return this.convent2Enhanceds(dbSources);
    }


    @Override
    public List<DbSourceEnhanced> convent2Enhanceds(List<? extends BasePo> pos) {
        List<DbSource> dbSources = (List<DbSource>) pos;
        List<DbSourceEnhanced> dbSourceEnhanceds = Lists.newArrayList();
        dbSources.forEach(e -> dbSourceEnhanceds.add(new DbSourceEnhanced(e)));
        return dbSourceEnhanceds;
    }


    public DbSourceEnhanced getEnhanceds(String serviceGatewayName, String env, UserContext userContext) {
        DbSource dbSource = new DbSource();
        dbSource.setServiceGatewayName(serviceGatewayName);
        dbSource.setEnv(env);
        dbSource = dbSourceDao.getOneByRecord(dbSource);

        if (dbSource == null) {
            return null;
        }

        return (DbSourceEnhanced) this.convent2Enhanced(dbSource);
    }

    public void updateDbSource(DbSource dbSource, UserContext userContext) {
        this.checkUpdate(dbSource);

        dbSource.setUpdateTime(new Date());

        dbSourceDao.updateByServiceGatewayNameAndEnv(dbSource);
    }

    private void checkUpdate(DbSource dbSource) {
        if (!Detect.notEmpty(dbSource.getServiceGatewayName()) || !Detect.notEmpty(dbSource.getEnv()) || !Detect.notEmpty(dbSource.getIp())
                || !Detect.notEmpty(dbSource.getPort()) || !Detect.notEmpty(dbSource.getDbName())
                || !Detect.notEmpty(dbSource.getUsername()) || !Detect.notEmpty(dbSource.getPassword()) || !Detect.isNumeric(dbSource.getPort())) {
            throw new HomedoException(ResponseEnum.PARAM_ERROR);
        }
        DataSource dataSource = null;
        try {
            dataSource = this.createDataSource(dbSource);
        } catch (Exception ex) {
            throw new HomedoException("[必须更改成能正确访问的数据源:" + ex.getMessage() + "]");
        } finally {
            if (dataSource != null) {
                ((DruidDataSource) dataSource).close();
            }
        }
    }


    private DataSource createDataSource(DbSource dbSource) throws SQLException {
        DruidConf newDruidConf = new DruidConf();
        BeanUtils.copyProperties(druidConf, newDruidConf);
        String url = "jdbc:mysql://" + dbSource.getIp() + ":" + dbSource.getPort() + "/" + dbSource.getDbName() + "?useOldAliasMetadataBehavior=yes&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8";
        newDruidConf.setUrl(url);
        newDruidConf.setUsername(dbSource.getUsername());
        newDruidConf.setPassword(dbSource.getPassword());

        return DruidDataSourceUtil.init(DruidDataSourceUtil.createDruidDataSource(newDruidConf));
    }
}
